package jam4j.lang;

import java.io.File;
import java.util.*;

import jam4j.TargetDef;
import jam4j.util.FallibleThunk;

final class ScriptTargetDef implements TargetDef {
    private final String name;
    private final Context context;
    private final List<ScriptActionDef> actionDefs =
        new ArrayList<ScriptActionDef>();
    private final List<ScriptTargetDef> dependencies =
        new ArrayList<ScriptTargetDef>();
    private final Set<Flag> flags = EnumSet.noneOf(Flag.class);
    private ScriptTargetDef includeTarget;
    
    final Scope scope = new Scope();

    ScriptTargetDef(String name, Context context) {
        this.name = name;
        this.context = context;
    }
    
    public String name() {
        return name;
    }
    
    public void addAction(ScriptActionDef def) {
        actionDefs.add(def);
    }
    
    public void addFlag(Flag flag) {
        flags.add(flag);
    }
    
    public List<ScriptTargetDef> dependencies() {
        return Collections.unmodifiableList(dependencies);
    }
    
    public ScriptTargetDef includeTarget() {
        if (includeTarget == null) {
            includeTarget = new ScriptTargetDef(name, context);
            includeTarget.flags.addAll(
                    EnumSet.of(Flag.INTERNAL, Flag.NOTFILE));
        }
        
        return includeTarget;
    }
    
    public Set<Flag> flags() {
        return Collections.unmodifiableSet(flags);
    }
    
    public void addDependency(ScriptTargetDef dependency) {
        dependencies.add(dependency);
    }
    
    public static void addActionToTargets(ScriptActionDef def) {
        for (ScriptTargetDef target : def.targets())
            target.actionDefs.add(def);
    }
    
    public <T, X extends Throwable> T runInScope(
            FallibleThunk<T, X> thunk) throws X {
        return context.runOnTarget(this, thunk);
    }
    
    public void scanForHeaders(File boundFile) {
        HeaderScanner.scanForHeaders(context, this, boundFile);
    }
}
